#include "members48.h"
#include "ui_members48.h"
#include "QJsonArray"
#include "QJsonDocument"
#include "QJsonObject"
#include "QNetworkAccessManager"
#include "QNetworkReply"
#include "QNetworkRequest"
#include "QUrl"
#include "QMessageBox"
#include "QTreeWidgetItem"
#include "QDebug"
#include "QPushButton"
#include "QDesktopServices"
#include "QFile"
#include "QFileDialog"
#include "QDir"
#include "QByteArray"
#include "QClipboard"
#include "QDesktopServices"
#include "QTimer"
#include "QPainter"
#include "loadingcircledialog.h"

Members48::Members48(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::Members48)
{
    ui->setupUi(this);

    // 初始化
    initTreeWidget();
    ui->statusbar->addWidget(ui->totalLabel);
    ui->statusbar->addWidget(ui->searchLabel);

    // 绑定信号
    void(Members48:: * flSignal)(QByteArray) = &Members48::fetchMemberListLoaded;
    connect(this,flSignal,this,&Members48::updateMemberList);


    // 从本地拉取成员数据 如果不存在则调用官网拉取数据
    QFile * file = new QFile(QDir::currentPath()+ "/" + DEAFULT_FILE_NAME);
    if(!file->exists()){
        getMemberList(false); // false 不比较 直接覆盖
    }else {
        importMembersJson(DEAFULT_FILE_NAME);
        getMemberList();
    }



    // 双击打开官网主页
    connect(ui->treeWidget, &QTreeWidget::itemDoubleClicked, this, &Members48::onItemDoubleClicked);

    // 点击按钮获取输入框内容
    connect(ui->searchBtn,&QPushButton::clicked,this,&Members48::searchMemberList);

    // 当搜索框被清空时候显示所有成员
    connect(ui->searchInp,&QLineEdit::textChanged,this,[this](){
        if(ui->searchInp->text().isEmpty())searchMemberList();
    });


    // 在 Members48 构造函数中添加
    ui->treeWidget->setContextMenuPolicy(Qt::CustomContextMenu); // 启用自定义右键菜单
    connect(ui->treeWidget, &QTreeWidget::customContextMenuRequested,
            this, &Members48::onCustomContextMenuRequested); // 连接右键菜单信号

    // 按下回车键搜索
    connect(ui->searchInp, &QLineEdit::returnPressed,
            this, &Members48::searchMemberList);

    // 更新成员数据
    connect(ui->actionupdate_action,&QAction::triggered,[this](){
        this->getMemberList(true,true);
    });

    // 导入数据
    connect(ui->actionimport_action,&QAction::triggered,[this](){
        QString url = QFileDialog::getOpenFileName(this,"打开文件",QDir::currentPath(),"(*.json)");
        QFile file(url);
        bool isOpen = file.open(QFile::ReadOnly);
        if(isOpen){
            if(QFile::OpenError==file.error()){
                QMessageBox::critical(this,"提示","读取文件失败!");
            }else {
                QMessageBox::information(this,"提示","读取文件成功!");
                emit fetchMemberListLoaded(file.readAll());
            }
        }

        file.close();
    });


    // 导出数据
    connect(ui->actionexport_action,&QAction::triggered,[this](){
        QString url = QFileDialog::getSaveFileName(this,"保存文件",QDir::currentPath(),"(*.json)");
        QFile file(url);
        bool isOpen = file.open(QFile::WriteOnly);
        if(isOpen){
            file.write(metaData.toUtf8());
            if(QFile::WriteError==file.error()){
                QMessageBox::critical(this,"提示","写出文件失败!");
            }else {
                QMessageBox::information(this,"提示","写出文件成功!");
            }
        }
        file.close();
    });

    // 打开仓库
    connect(ui->actionupdate_action_2,&QAction::triggered,this,&Members48::openGitee);

    // 关于
    connect(ui->actionabout_action,&QAction::triggered,this,&Members48::showAboutDialog);

}

Members48::~Members48()
{
    delete ui;
}

// 打开仓库地址
void Members48::openGitee(){
    QUrl url("https://gitee.com/jhtools/members48-ui");
    if(url.isValid()){
        QDesktopServices::openUrl(url);
    }
}


// 关于提示
void Members48::showAboutDialog() {
    QString version = QApplication::applicationVersion();
    int lastDotPos = version.lastIndexOf('.');
    QMessageBox::about(nullptr, "关于",
                       "当前版本: V" + ((lastDotPos != -1) ? version.left(lastDotPos) : version) + "\n" +
                       "作者: Goog、2025 \n" + "警告: 本软件完全开源免费且仅供学习交流,禁止用于非法和商业用途。" + "\n" +
                           "Email: smilewychina@qq.com");

}

// 导出成员数据
void Members48::exportMembersJson(QString url=DEAFULT_FILE_NAME){
    if(url==DEAFULT_FILE_NAME)url = QDir::currentPath() + "/"+ url;
    if(!this->metaData.isEmpty()){
        QFile * file = new QFile(url);
        file->open(QFile::WriteOnly);
        file->write(this->metaData.toUtf8());
        file->close();
    }else {
        QMessageBox::critical(this,"提示","保存失败,请先更新成员数据!");
    }
}

// 导入成员数据
void Members48::importMembersJson(QString url=DEAFULT_FILE_NAME){
    if(url==DEAFULT_FILE_NAME)url = QDir::currentPath()+ "/" + url;
    QFile * file = new QFile(url);
    file->open(QFile::ReadOnly);
    if(!file->exists()){
        QMessageBox::critical(this,"提示","导入失败文件不存在!");
    }else {
        // 文件内容
        QByteArray fileContent = file->readAll();
        file->close();
        // 获取信息成功
        emit fetchMemberListLoaded(fileContent);
    }

}

// 初始化树形控件
void Members48::initTreeWidget(){
    // ================= 表头（支持国际化） =================
    QStringList headers = {
        tr("姓名"),    // Name
        tr("拼音"),    // Pinyin
        tr("团队"),    // Group
        tr("队伍"),    // Team
        tr("生日"),    // Birthday
        tr("期数"),    // Generation
        tr("昵称"),    // Nickname
        tr("加入时间"), // Join Date
        tr("身高"),    // Height
        tr("星座"),    // Zodiac
        tr("出生地"),  // Birthplace
        tr("特长"),    // Specialty
        tr("爱好")     // Hobby
    };
    // 设置表头样式（文本居中 + 其他可选样式）
    ui->treeWidget->header()->setStyleSheet(
        "QHeaderView::section {"
        "    text-align: center;"        // 文本居中
        "    background-color: #FFFFFF;" // 表头背景色
        "    padding: 2px;"              // 内边距
        "    border: 1px solid #cccccc;" // 边框
        "}"
        );
    ui->treeWidget->setSortingEnabled(true);
    ui->treeWidget->sortByColumn(0, Qt::AscendingOrder); // 按姓名排序
    // 在填充数据后，让列宽自动适应内容
    ui->treeWidget->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
    // 获取表头对象并设置默认对齐方式
    QHeaderView *header = ui->treeWidget->header();
    header->setDefaultAlignment(Qt::AlignCenter); // 全局居中
    ui->treeWidget->setHeaderLabels(headers);
}

// 解析数据
QJsonObject Members48::parseMemberList(QByteArray mb){
    return QJsonDocument::fromJson(mb).object();
}

// 比较本地和官网成员列表数据
void Members48::diffMemberList(QByteArray md,bool showTip){
    // 如果本地数据为空则不进行比较

    if(!metaData.isEmpty()){
        QJsonDocument onlineDoc =  QJsonDocument::fromJson(md);
        QJsonDocument localDoc =  QJsonDocument::fromJson(metaData.toUtf8());
        QJsonObject onlineObj = onlineDoc.object();
        QJsonObject localObj = localDoc.object();
        int onlineCount =  onlineObj["total"].toString().toInt();
        int localCount =  localObj["total"].toString().toInt();

        //qDebug() << "在线:" << onlineCount << " 本地:" << localCount;
        if(onlineCount!=localCount){
            QString tip = QString("检测本地和官网成员数不一致,是否更新本地成员数据? \n 本地成员数: %1 , 官网成员数: %2").arg(QString::number(localCount)).arg(QString::number(onlineCount));
            QMessageBox msgBox;
            msgBox.setWindowTitle("提示");
            msgBox.setText(tip);
            msgBox.setIcon(QMessageBox::Question);
            // 添加自定义按钮（文本和角色）
            QPushButton* saveButton = msgBox.addButton("确定", QMessageBox::AcceptRole);  // 接受角色
            QPushButton* cancelButton = msgBox.addButton("取消", QMessageBox::RejectRole); // 拒绝角色
            // 执行对话框
            msgBox.exec();
            if(msgBox.clickedButton() == cancelButton){
                return;
            }
        }else {
            if(showTip){
                qDebug() << "当前已经是最新数据！";
                QMessageBox::information(this,"提示","当前已是最新数据!");

            }
            return;
        }
    }
    emit fetchMemberListLoaded(md);
}

// 更新成员列表数据
void Members48::updateMemberList(QByteArray md){
    // 保存在元数据
    this->metaData = md;
    // 获取信息成功
    QJsonObject data = this->parseMemberList(md);
    m_Total = data["total"].toString().toInt();
    ui->totalLabel->setText("成员总数: "+QString::number(m_Total));
    // 保存并加载
    if(this->saveMemberList(data["rows"].toArray())){

        loadMemberListToTreeWidget(m_List);
    }

    // 写出到文件
    this->exportMembersJson();
    //QMessageBox::information(this,"提示","更新成员列表成功!");
}

// 获取成员列表
void Members48::getMemberList(bool isDiff,bool showTip){

    // 初始化网络请求管理器（必须实例化对象）
    QNetworkAccessManager *manager = new QNetworkAccessManager(this); // 添加 this 便于内存管理

    // 设置请求地址，补充时间戳避免缓存
    qint64 timestamp = QDateTime::currentMSecsSinceEpoch();
    QUrl url(QString("https://h5.48.cn/resource/jsonp/allmembers.php?gid=00&_=%1").arg(timestamp));

    // 创建请求并添加必要的头信息（例如 User-Agent）
    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::UserAgentHeader, "Mozilla/5.0 (Qt Network Client)");

    // 发起 GET 请求并连接信号槽
    QNetworkReply *reply = manager->get(request);

    static LoadingCircleDialog dialog(this);

    if(showTip)dialog.showLoading("正在拉取数据...");


    // 使用显式 this 捕获处理响应（C++20+ 要求）
    connect(reply, &QNetworkReply::finished, [=,this]() { // [=, this] 显式捕获
        if(showTip){
            dialog.setText("拉取数据完成!");
            dialog.hideLoading();
        }

        if(reply->error() == QNetworkReply::NoError){ 
            isDiff?diffMemberList(reply->readAll(),showTip):(emit fetchMemberListLoaded(reply->readAll()));
        }else {
            QMessageBox::critical(this,"提示","从官网获取成员数据失败!");
        }
    });
}

// 保存成员json对象转换
bool Members48::saveMemberList(QJsonArray list){
    // 每次保存清空一下
    m_List.clear();

    // 预先分配内存
    m_List.reserve(list.size());

    for(int i=0;i<list.size();i++){
        Member mb;
        // 提前提取 JSON 对象，避免重复调用 toObject()
        QJsonObject obj = list[i].toObject();
        // 使用实际字段名提取数据
        mb.abbr = obj["abbr"].toString();
        mb.birth_day = obj["birth_day"].toString();       // 注意字段名对应
        mb.birth_place = obj["birth_place"].toString();
        mb.blood_type = obj["blood_type"].toString();
        mb.catch_phrase = obj["catch_phrase"].toString();
        mb.company = obj["company"].toString();
        mb.experience = obj["experience"].toString();
        mb.fname = obj["fname"].toString();
        mb.gcolor = obj["gcolor"].toString();
        mb.gid = obj["gid"].toString();
        mb.gname = obj["gname"].toString();
        mb.height = obj["height"].toString();
        mb.hobby = obj["hobby"].toString();
        mb.is_group_new = obj["is_group_new"].toString();
        mb.join_day = obj["join_day"].toString();
        mb.nickname = obj["nickname"].toString();
        mb.pid = obj["pid"].toString();
        mb.pinyin = obj["pinyin"].toString();
        mb.pocket_id = obj["pocket_id"].toString();
        mb.pname = obj["pname"].toString();
        mb.ranking = obj["ranking"].toString();
        mb.sid = obj["sid"].toString();
        mb.sname = obj["sname"].toString();
        mb.speciality = obj["speciality"].toString();
        mb.star_sign_12 = obj["star_sign_12"].toString();
        mb.star_sign_48 = obj["star_sign_48"].toString();
        mb.status = obj["status"].toString();
        mb.tcolor = obj["tcolor"].toString();
        mb.tid = obj["tid"].toString();
        mb.tname = obj["tname"].toString();
        mb.tieba_kw = obj["tieba_kw"].toString();
        mb.weibo_uid = obj["weibo_uid"].toString();
        mb.weibo_verifier = obj["weibo_verifier"].toString();
        m_List.append(mb);
    }
    return true;
}

// 将保存的成员对象数组输出到树形控件
void Members48::loadMemberListToTreeWidget(QList<Member> list){
    ui->treeWidget->clear(); // 每次加载树形数据时候清空一下
    for(const Member &mb : list){
        QStringList rs = {
            mb.sname,        // 0 - 姓名
            mb.pinyin,       // 1 - 拼音
            mb.gname,        // 2 - 团队
            mb.tname,        // 3 - 队伍
            mb.birth_day,    // 4 - 生日
            mb.pname,        // 5 - 期数
            mb.nickname,     // 6 - 昵称
            mb.join_day,     // 7 - 加入时间
            mb.height,       // 8 - 身高
            mb.star_sign_12, // 9 - 星座
            mb.birth_place,  // 10 - 出生地
            mb.speciality,   // 11 - 特长
            mb.hobby,        // 12 - 爱好
            mb.weibo_uid ,   // 13 - 微博 UID（新增列）
            mb.sid,          // 14 - 成员唯一编号 SID（新增列）
            mb.pocket_id     // 15 - 口袋id
        };

        ui->treeWidget->addTopLevelItem(new QTreeWidgetItem(rs));
    }
    // 隐藏微博 UID 列（在初始化时调用一次）
    ui->treeWidget->setColumnCount(16); // 总列数 = 13 原列 + 2 新增列
    ui->treeWidget->setColumnHidden(13, true); // 隐藏第 13 列
    ui->treeWidget->setColumnHidden(14, true); // 隐藏第 14 列
    ui->treeWidget->setColumnHidden(15, true); // 隐藏第 15 列
}

// 搜索过滤成员
void Members48::searchMemberList() {
    QString text = ui->searchInp->text().trimmed();

    // 清空搜索框时恢复显示全部内容
    if (text.isEmpty()) {
        showAllItems();
        ui->searchLabel->setText("搜索匹配成员数: 0");
        return;
    }

    // 执行搜索逻辑
    QList<QTreeWidgetItem*> allItems = getAllTreeItems();
    int matchCount = 0;

    for (QTreeWidgetItem *item : allItems) {
        bool isMatch = false;
        for (int col = 0; col < ui->treeWidget->columnCount(); ++col) {
            if (item->text(col).contains(text, Qt::CaseInsensitive)) {
                isMatch = true;
                break;
            }
        }
        item->setHidden(!isMatch);
        if (isMatch) matchCount++;
    }

    ui->searchLabel->setText("搜索匹配成员数: " + QString::number(matchCount));
}

// 获取所有项
QList<QTreeWidgetItem*> Members48::getAllTreeItems() {
    QList<QTreeWidgetItem*> items;

    // 递归遍历函数
    std::function<void(QTreeWidgetItem*)> addChildren;
    addChildren = [&](QTreeWidgetItem *parent) {
        if (!parent) return;
        for (int i = 0; i < parent->childCount(); ++i) {
            QTreeWidgetItem *child = parent->child(i);
            items.append(child);
            addChildren(child); // 递归处理子项
        }
    };

    // 遍历顶层项
    for (int i = 0; i < ui->treeWidget->topLevelItemCount(); ++i) {
        QTreeWidgetItem *topItem = ui->treeWidget->topLevelItem(i);
        items.append(topItem);
        addChildren(topItem);
    }

    return items;
}

// 显示所有项 重置隐藏状态
void Members48::showAllItems() {
    QList<QTreeWidgetItem*> allItems = getAllTreeItems();
    for (QTreeWidgetItem *item : allItems) {
        item->setHidden(false); // 取消隐藏
    }
    ui->treeWidget->expandAll(); // 可选：展开所有项
}

//双击打开官网主页
void Members48::onItemDoubleClicked(QTreeWidgetItem *item, int column) {
    Q_UNUSED(column); // 忽略列参数

    // 获取微博 UID（假设存储在第 13 列，或通过 Qt::UserRole）
    QString memberSID = item->text(14); // 方式 1：隐藏列
    // 或 QString weiboUid = item->data(0, Qt::UserRole).toString(); // 方式 2：UserRole

    if (!memberSID.isEmpty()) {
        QUrl url("https://www.snh48.com/member_details.html?sid=" + memberSID);
        if (url.isValid()) {
            QDesktopServices::openUrl(url);
        } else {
            QMessageBox::warning(this, "错误", "无效的成员SID");
        }
    } else {
        QMessageBox::information(this, "提示", "该成员没有SID");
    }
}

// 右键菜单触发
void Members48::onCustomContextMenuRequested(const QPoint &pos) {
    QTreeWidgetItem *item = ui->treeWidget->itemAt(pos); // 获取鼠标位置下的项
    if (!item) return; // 未点击到项时不显示菜单

    // 创建菜单
    QMenu menu;
    QAction *actionWeibo = menu.addAction("访问该成员微博主页");
    QAction *actionWebSite = menu.addAction("访问该成员官网主页");
    QAction *actionCopyPocketId = menu.addAction("复制该成员口袋ID");
    QAction *actionCopySId = menu.addAction("复制该成员SID");
    // 连接菜单动作到槽函数
    connect(actionWeibo, &QAction::triggered, this, &Members48::openWeiboProfile);
    connect(actionWebSite, &QAction::triggered, this, &Members48::openWebSite);
    connect(actionCopyPocketId, &QAction::triggered, this, &Members48::copyPocketId);
    connect(actionCopySId, &QAction::triggered, this, &Members48::copySID);
    // 显示菜单
    menu.exec(ui->treeWidget->viewport()->mapToGlobal(pos));
}

// 打开微博主页
void Members48::openWeiboProfile() {
    QTreeWidgetItem *item = ui->treeWidget->currentItem(); // 获取当前选中项
    if (!item) return;

    // 获取微博 UID（假设存储在第 13 列，或通过 Qt::UserRole）
    QString weiboUid = item->text(13); // 方式 1：隐藏列
    // 或 QString weiboUid = item->data(0, Qt::UserRole).toString(); // 方式 2：UserRole

    if (!weiboUid.isEmpty()) {
        QUrl url("https://weibo.com/u/" + weiboUid);
        if (url.isValid()) {
            QDesktopServices::openUrl(url);
        } else {
            QMessageBox::warning(this, "错误", "无效的微博 UID");
        }
    } else {
        QMessageBox::information(this, "提示", "该成员未关联微博账号");
    }
}

// 打开官网主页
void Members48::openWebSite() {
    QTreeWidgetItem *item = ui->treeWidget->currentItem(); // 获取当前选中项
    if (!item) return;

    // 获取微博 UID（假设存储在第 14 列，或通过 Qt::UserRole）
    QString memberSID = item->text(14); // 方式 1：隐藏列
    // 或 QString weiboUid = item->data(0, Qt::UserRole).toString(); // 方式 2：UserRole

    if (!memberSID.isEmpty()) {
        QUrl url("https://www.snh48.com/member_details.html?sid=" + memberSID);
        if (url.isValid()) {
            QDesktopServices::openUrl(url);
        } else {
            QMessageBox::warning(this, "错误", "无效的SID");
        }
    } else {
        QMessageBox::information(this, "提示", "没有找到SID");
    }
}

// 复制成员口袋用户id
void Members48::copyPocketId(){
    QTreeWidgetItem *item = ui->treeWidget->currentItem(); // 获取当前选中项
    if (!item) return;

    // 成员口袋用户id
    QString memberPocketId = item->text(15); // 方式 1：隐藏列

    QClipboard* clipboard = QApplication::clipboard();

    // 复制剪切板信息
    clipboard->setText(memberPocketId);

    // 复制成功提示
    QMessageBox::information(this,"提示","复制成员口袋ID成功!");
}


void Members48::copySID(){
    QTreeWidgetItem *item = ui->treeWidget->currentItem(); // 获取当前选中项
    if (!item) return;

    // 成员口袋用户id
    QString SId = item->text(14); // 方式 1：隐藏列

    QClipboard* clipboard = QApplication::clipboard();

    // 复制剪切板信息
    clipboard->setText(SId);

    // 复制成功提示
    QMessageBox::information(this,"提示","复制成员SID成功!");
}


